/**
 * \file graph.h 
 * \brief Declaração de estruturas de dados essenciais para os grafos
 *
 * \description
 *
 * Os grafos utilizados neste trabalho são gráfos não direccionados.
 */
# ifndef GRAPH_DEFINITION
# define GRAPH_DEFINITION

# include <stdlib.h>
# include <math.h>
# include "../../base/types.h"
# include "../lists/linked-list.h"
# include "../lists/queue.h"
# include "../../io/logs/logSystem.h"

# define CONNECTED 1
# define DISCONNECTED 0

typedef struct {
	int size;
	int maxColors;
	int nodes;
	int *edge;
	int *color;
	int *label;
} Graph;

/**
 * \brief Declara este grafo em memória.
 * \param size Número de nodos do grafo.
 * \return Grafo com memória alocada para este.
 */
Graph * newGraph(int size);
/**
 * \brief Diz que um vertice é adjacente de outro
 * \param g Grafo
 * \param verticeA indice de um vertice (Começa em 0)
 * \param verticeB indice de outro vertice (Começa em 0)
 * \return 1 se A e B tiverem uma aresta que os liga.
 */
int adjacent (Graph *g, int verticeA, int verticeB);
/**
 * \brief Dado um grafo e um indice de um vertice calcula todos os adjacentes deste.
 *
 * \param g Grafo
 * \param vertice Indice do vertice Pai
 * \param result Array de inteiros de tamanho igual ao número de nodos.
 * \return Array de indices dos vertices filho
 */
int adjacentList (Graph *g, int vertice, int *result);
/***
 * \brief Dado uma aresta (indice) diz os vertices que a compoem.
 * \param edge Indice da aresta em causa
 * \param vA Passar como apontador para fazer uma alteração em memoria
 * \param vB Idem
 */
void getVertices (int edge, int *vA, int *vB);

/**
 * \brief Liga 2 vertices um ao outro (cria uma aresta)
 * \param g Grafo
 * \param vA 1º vertice
 * \param vB 2º vertice
 * \return 1 se conseguiu 0 se não conseguiu
 */

int createEdge (Graph *g, int vA, int vB);
/**
 * \brief Atribui um valor concreto à ligação (para coloração)
 * \param g Grafo
 * \param vA Primeiro vertice
 * \param vB Segundo vertice
 * \param value Valor a atribuir
 */
int setEdgeValue (Graph *g, int vA, int vB, int value);
/**
 * \brief Vai buscar o valor associado à aresta
 * \param g grafo
 * \param vA vertice 1
 * \param vB vertice 2
 * \return Valor ou -1 se não existir essa aresta
 */
int getEdgeValue (Graph *g, int vA, int vB);

/**
 * \brief Da os subgrafos connectados
 * \param g Grafo base
 * \return Lista de subgrafos
 * \description
 *
 * Pega num grafo e divide-o em subgrafos,
 * sendo que todos eles são conectados.
 */
LinkedList * getConnectedSubGraphs (Graph *g);

/**
 * \brief Liberta da memória a estrutura
 * \param g Grafo
 */
void freeGraph (Graph *g);
# endif
